/*
 * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
 * Copyright (c) 1995 Martin Husemann
 * Some structure declaration borrowed from Paul Popelka
 * (paulp@uts.amdahl.com), see /sys/msdosfs/ for reference.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    This product includes software developed by Martin Husemann
 *    and Wolfgang Solfrank.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * $NetBSD: dosfs.h,v 1.4 1997/01/03 14:32:48 ws Exp $
 * $FreeBSD: src/sbin/fsck_msdosfs/dosfs.h,v 1.3 2003/12/26 17:24:37 trhodes Exp $
 */

#ifndef _FATCACHE_H_
#define _FATCACHE_H_
#include "fsck_tree.h"
#include "stddef.h"
#include "fsck_boot.h"
/******FAT cache struct ****/

typedef struct FSCK_CACHE_S
{
    struct FSCK_CACHE_S *next;
    cl_t head;
    u_int length;
}FSCK_CACHE_S;

typedef struct FSCK_CACHE_CLUSTER_CHAIN_S
{
    struct FSCK_CACHE_S* child;
    cl_t    head;                   /* pointer to start of chain */
    u_int length;               /* how many cluster this file contains*/
    RBT_ENTRY(FSCK_CACHE_CLUSTER_CHAIN_S) rb;
    u_int flag;
    u_int segments;
}FSCK_CACHE_CLUSTER_CHAIN_S;

#define FSCK_BIT(x,n)    (((x)>>(n)) & 0x1)
#define SET_BIT(x,n)    do{ \
    x |= 1<<n;}while (0)
#define CLEAR_BIT(x,n)  do{ \
    x &= ~(1<<n);}while (0)

#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

#define container_of(ptr, type, member) \
    ((type *)((unsigned long)(ptr) - offsetof(type, member)))

FSCK_CACHE_CLUSTER_CHAIN_S* FSCK_CACHE_NewChain(void);
FSCK_CACHE_CLUSTER_CHAIN_S* FSCK_CACHE_FindChain(void* pstHead, FSCK_CACHE_CLUSTER_CHAIN_S* pstChain);
FSCK_CACHE_CLUSTER_CHAIN_S* FSCK_CACHE_NextChain(FSCK_CACHE_CLUSTER_CHAIN_S* pstChain);
FSCK_CACHE_CLUSTER_CHAIN_S* FSCK_CACHE_InsertChain(void* pstHead, FSCK_CACHE_CLUSTER_CHAIN_S* pstChain);
FSCK_CACHE_CLUSTER_CHAIN_S* FSCK_CACHE_MinChain(void* pstHead);
void FSCK_CACHE_RemoveChain(void* pstHead, FSCK_CACHE_CLUSTER_CHAIN_S* pstChain);
void FSCK_CACHE_DumpChain(FSCK_CACHE_CLUSTER_CHAIN_S *fat);

FSCK_CACHE_S* FSCK_CACHE_New(void);
FSCK_CACHE_S* FSCK_CACHE_Next(FSCK_CACHE_CLUSTER_CHAIN_S* fat,unsigned int clus, unsigned int* cl);
void FSCK_CACHE_Add(FSCK_CACHE_CLUSTER_CHAIN_S *fatentry , FSCK_CACHE_S *new);
int FSCK_CACHE_AddToTail(FSCK_CACHE_CLUSTER_CHAIN_S *fatentry , FSCK_CACHE_S *new);
void FSCK_CACHE_SetNext(u_char* fat ,unsigned int cl ,unsigned int  next);
void FSCK_CACHE_Trunc(FSCK_BOOT_SECTOR_S * pstBoot, FSCK_CACHE_CLUSTER_CHAIN_S* fat, unsigned int cl);
void FSCK_CACHE_Free(void* pTree);

#endif
